<template>
  <div class="my_page_container">
    <q-splitter
      class="bg-white"
      v-model="splitterRatio"
      style="height: 550px"
    >
      <template v-slot:before>
        <div class="row q-pa-xs q-gutter-sm">
          <q-input outlined dense color="base" style="width: 130px">
            <template v-slot:append>
              <q-icon name="search" color="indigo" />
            </template>
          </q-input>
          <q-btn
            dense
            outline
            color="primary"
            label="刷新"
            icon="refresh"
          />
        </div>
        <q-separator />
        <q-scroll-area style="height: 450px; max-width: 300px">
          <div class="q-pa-sm my-text-overflow">
            <q-tree
              icon="mdi-key"
              ref="myNavTreeRef"
              :nodes="uTreeList"
              node-key="sid"
              label-key="name"
              selected-color="primary"
              v-model:selected="myNavTreeSelectedItem"
              @update:selected="onNavTreeSelected"
            />
          </div>
        </q-scroll-area>
      </template>
      <template v-slot:after>
        <q-scroll-area style="height: 500px; max-width: 1000px;">
          <div
            class="my-canvas-container"
            :style="{
            backgroundColor: store.canvas.backgroundColor,
            backgroundImage: `url(${store.canvas.backgroundImage})`
        }"
          >
            <template v-for="(component) in store.components" :key="component.sid">
              <div
                class="my-component-container"
                :style="{
                    left: component.position.x + 'px',
                    top: component.position.y + 'px',
                    width: component.position.w + 'px',
                    height: component.position.h + 'px',
                    zIndex: component.shape.zIndex,
                    transform: component.shape.transform? `rotate(${component.shape.transform}deg)`:'rotate(0deg)',
                }"
              >
                <component
                  :is="parseView(component)"
                  :detail="component"
                  :dynamic-data="varTbl"
                  :current-switch="true"
                  :motion-type-arr="motionTypeList"
                  :event-type-arr="eventTypeList"
                  :operator-type-arr="operatorTypeList"
                  :operation-type-arr="eventOperationTypeList"
                  @update-event="updateEvent"
                />
              </div>
            </template>
          </div>
          <ShowMsgDlg ref="myMsgDlgRef" :message="myEventMsg"/>
        </q-scroll-area>
      </template>
    </q-splitter>
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, onUnmounted, reactive, ref, watch } from 'vue';
import { useCatalogTool } from 'src/hook/common/useCatalogTool';
import { cinBaseUrlAPI } from 'src/util/CinBaseConst';
import { useCommonTree } from 'src/hook/common/useCommonTree';
import { useEditorExecPageComponents } from 'src/hook/editor/useEditorExecPageComponents';
import { useEditorStore } from 'src/stores/editorStore';
import { CEventMsgItem, CGraphEntity, EnumEditorEvent, EPageType } from 'stores/editorModels';
import { storeToRefs } from 'pinia';
import { parseViewName } from 'src/hook/common/useComponentParse';
import { EnumEventOperationType } from 'src/util/SelectBoxOption';
import { useUivCatalogTbl } from 'src/hook/editor/useUivCatalogTbl';
import { uivCatalogType } from 'src/util/UivBaseConst';
import { useCommonStore } from 'stores/commonStore';
import { socket } from 'src/socket/websocket';
import { useScadaPacket } from 'src/hook/editor/useScadaPacket';

import BaseComponent from 'components/views/BaseComponent.vue';
import ShowMsgDlg from 'pages/preview/ShowMsgDlg.vue';

export type ShowMsgDlgInstance = InstanceType<typeof ShowMsgDlg>;

export default defineComponent({
  name: 'GraphIndex',
  extends: BaseComponent,
  components: {
    ShowMsgDlg
  },
  setup (props, context) {
    //*********************************************************
    //          store
    //*********************************************************
    //store
    const store = useEditorStore();
    const {
      project,
      canvas,
      components,
      componentState
    } = storeToRefs(store);

    //数据库store
    const commonStore = useCommonStore();
    const {
      varTbl
    } = storeToRefs(commonStore);

    //*********************************************************************************************
    //      splitter
    //*********************************************************************************************
    //分割组件分割比例30%
    let splitterRatio = ref(20);

    //*********************************************************************************************
    //      查询模块
    //*********************************************************************************************
    //查询输入参数
    let queryParam = reactive({
      projectId: 0,
      pageId: 0
    });

    //*********************************************************************************************
    //            列表对应数据
    //*********************************************************************************************
    //导航树
    const {
      uTreeList,
      getCurrentTree,
      convertToTreeItem
    } = useCommonTree();

    //项目页面树
    let myNavTreeSelectedItem = ref('');
    let myNavTreeRef = ref(null);

    //后台读取数据
    const getCurrentTreeNav = () => {
      let param = {
        id: project.value.id
      }

      //获取项目页面树
      getCurrentTree(cinBaseUrlAPI.CIN_PROJECT_VO_TREE, param);
    }

    //导航树选择事件
    const onNavTreeSelected = () => {
      if (myNavTreeRef.value) {
        let map = convertToTreeItem(myNavTreeSelectedItem.value);
        if (map !== null) {
          queryParam.projectId = map.parentId;
          queryParam.pageId = map.sonId;

          //读取对应页面各种组件
          if (queryParam.pageId > 0) {
            store.setPage(EPageType.EXIST_PAGE, queryParam.pageId);
            getCurrentPageInfo();
          }
        }
      }
    };

    //*********************************************************
    // 当前页面组件读写
    //*********************************************************
    const {
      registerRecvComponentCB,
      getCurrentPageInfo
    } = useEditorExecPageComponents();

    //*********************************************************
    //          动态组件解析
    //*********************************************************
    // 依据名称解析成vue组件
    const parseView = (com: CGraphEntity) => {
      return parseViewName(com);
    };

    //*********************************************************************************************
    //      读取目录
    //*********************************************************************************************
    const {
      findCatalogLabel,
      findCatalogId
    } = useCatalogTool();

    const {
      operatorTypeList,
      eventOperationTypeList,
      eventTypeList,
      motionTypeList,
      getUivCatalog,
      removeUivCatalog
    } = useUivCatalogTbl();

    //*********************************************************
    // 应用信息
    //*********************************************************
    //播放窗口
    let myMsgDlgRef = ref<ShowMsgDlgInstance|null>(null);
    let myEventMsg = ref<CEventMsgItem>({
      operationType: '',
      url: '',
      msg: ''
    });

    //测试事件
    const onClick = () => {
      alert('父节点单击！');
    }

    //测试事件
    const testEvent = () => {
      let msg: CEventMsgItem = {
        operationType: EnumEventOperationType.OPERATION_OPEN_URL,
        url: 'https://www.baidu.com',
        msg: ''
      }

      updateEvent(msg);
    }

    //更新
    const updateEvent = (msg: CEventMsgItem) => {
      switch (msg.operationType) {
        case EnumEventOperationType.OPERATION_OPEN_URL:
          window.open(msg.url, '_blank');
          break;
        case EnumEventOperationType.OPERATION_PLAY_VIDEO:
          if (myMsgDlgRef.value) {
            myEventMsg.value.operationType = msg.operationType;
            myEventMsg.value.url = msg.url;
            myEventMsg.value.msg = msg.msg;
            myMsgDlgRef.value.show('播放视频');
          }
          break;
        case EnumEventOperationType.OPERATION_PLAY_AUDIO:
          if (myMsgDlgRef.value) {
            myEventMsg.value.operationType = msg.operationType;
            myEventMsg.value.url = msg.url;
            myEventMsg.value.msg = msg.msg;
            myMsgDlgRef.value.show('播放音频');
          }
          break;
        case EnumEventOperationType.OPERATION_SEND_CHAT:
          break;
        case EnumEventOperationType.OPERATION_SEND_EMAIL:
          break;
      }
    }

    //*********************************************************
    //          websocket
    //*********************************************************
    //socket通信函数
    const {
      wsRegisterVariable,
      wsReadVariable
    } = useScadaPacket();

    //*********************************************************
    //          初始化
    //*********************************************************
    //初始化
    const initComponents = () => {
      //数据库清空
      commonStore.initVariableTbl();

      //注册收到一个组件数据后回调函数,创建变量数据库
      registerRecvComponentCB(createCurrentPageVariableTbl);
    }

    //*********************************************************
    //          启动
    //*********************************************************
    //从页面组件树中，创建当前页面变量表
    const createCurrentPageVariableTbl = () => {
      //创建变量数据库
      components.value.forEach((item) => {
        item.dataItem.forEach((el) => {
          //组件对应的数据节点
          commonStore.addVariableTbl(el.variableValue, 0);
        });
      });

      //注册变量,读取变量
      if (socket) {
        console.log('注册变量、读取变量值');
        wsRegisterVariable(socket, varTbl.value);
        wsReadVariable(socket, varTbl.value);
      }
    }

    //*********************************************************************************************
    //      启动模块
    //*********************************************************************************************
    //监视检索框
    watch(() => project.value.id, () => {
      getCurrentTreeNav();
    }, { deep: true });

    //监视树形组件数据变化
    watch(() => uTreeList, () => {
      if (uTreeList.value.length > 0) {
        if (uTreeList.value[0].children.length > 0) {
          let map = convertToTreeItem(uTreeList.value[0].children[0].sid);
          if ((map !== null) && (map.sonId > 0)) {
            store.setPage(EPageType.EXIST_PAGE, map.sonId);
            getCurrentPageInfo();
          }
        }
      }
    }, { deep: true });

    //挂载数据
    onMounted(() => {
      //页面树
      getCurrentTreeNav();

      //初始化组件表，数据表
      initComponents();

      //读取cataItem
      getUivCatalog(uivCatalogType.COMPARE_OPERATOR_TYPE_CODE);
      getUivCatalog(uivCatalogType.EVENT_OPERATION_TYPE_CODE);
      getUivCatalog(uivCatalogType.EVENT_TYPE_CODE);
      getUivCatalog(uivCatalogType.MOTION_TYPE_CODE);
    });

    //销毁数据
    onUnmounted(() => {
      //store清空
      store.initCanvas();
      store.initComponents();
      commonStore.initVariableTbl();

      //cataItem
      removeUivCatalog(uivCatalogType.COMPARE_OPERATOR_TYPE_CODE);
      removeUivCatalog(uivCatalogType.EVENT_OPERATION_TYPE_CODE);
      removeUivCatalog(uivCatalogType.EVENT_TYPE_CODE);
      removeUivCatalog(uivCatalogType.MOTION_TYPE_CODE);
    });

    return {
      splitterRatio,

      store,
      project,
      canvas,
      components,
      componentState,

      myNavTreeSelectedItem,
      uTreeList,
      myNavTreeRef,
      getCurrentTreeNav,
      onNavTreeSelected,

      findCatalogLabel,
      findCatalogId,

      varTbl,
      operatorTypeList,
      eventOperationTypeList,
      eventTypeList,
      motionTypeList,

      myMsgDlgRef,
      myEventMsg,

      onClick,
      parseView,
      updateEvent,

      EnumEditorEvent
    }
  }
})

</script>

<style lang="scss" scoped>
.my-canvas-container {
    background-color: white;
    margin: 1px;
    padding: 2px;
    width: 100%;
    height: calc(100vh - 10px);
    position: relative;

    .my-component-container {
      position: absolute;
    }
  }
</style>
